using Bean.Entity;
using Bean.Entity.Constant;
using Bean.Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace Bean.Core.Api.Controllers;

/// <summary>
/// Redis 操作
/// </summary>
[Route("api")]
[ApiController]
public class RedisController : ControllerBase
{
    private readonly ILogger<RedisController> _logger;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="logger"></param>
    public RedisController(ILogger<RedisController> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// 保存数据到Redis中
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    [HttpPost("set/str")]
    public async Task<ApiResponse<bool>> SetAsync([FromBody] RedisDataParam param)
    {
        var response = await RedisHelper.SetAsync(param.Key, param.Data, TimeSpan.FromSeconds(param.Second));

        return ApiResponse<bool>.Success(response);
    }

    /// <summary>
    /// 获取Redis中的值
    /// </summary>
    /// <returns></returns>
    [Route("get/str")]
    public async Task<ApiResponse<string>> GetAsync([FromQuery] string key)
    {
        var response = await RedisHelper.GetAsync<string>(key);

        return ApiResponse<string>.Success(response);
    }

    /// <summary>
    /// 往队列中推送消息
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    [HttpPost("set/queue")]
    public async Task<ApiResponse<bool>> SetQueueAsync([FromBody] RedisDataParam param)
    {
        try
        {
            // 检查传入的参数是否为空
            if (param?.Data == null)
            {
                return ApiResponse<bool>.Error("队列名称或消息内容不能为空");
            }

            // 调用 RedisHelper 将消息推送到队列
            var result = await RedisHelper.RPushAsync(param.Key, param.Data);
            
            var queue = new  RedisQueue(param.Key);
            
            queue.Send(JsonConvert.SerializeObject(param.Data));

        }
        catch (Exception ex)
        {
            // 异常捕获并返回失败响应
            return ApiResponse<bool>.Error($"发生错误: {ex.Message}");
        }

        return ApiResponse<bool>.Success(true);
    }

    /// <summary>
    /// 发布Redis值
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<ApiResponse<long>> PublishAsync([FromBody] RedisDataParam param)
    {
        // 锁的键名称，可以根据需要调整
        var lockKey = SysConstant.lockKey(param.Key);

        // 锁的过期时间（例如 3 秒）
        var lockTimeout = TimeSpan.FromSeconds(3);

        _logger.LogInformation("测试");
        // 尝试设置锁
        var lockAcquired = await RedisHelper.SetNxAsync(lockKey, "locked");
        await RedisHelper.ExpireAsync(lockKey, lockTimeout);
        if (!lockAcquired)
        {
            // 如果未能获取到锁，返回锁定失败的响应
            return ApiResponse<long>.Error($"操作被锁定 等待3秒后再试", 423); // 423 错误代码表示“锁定失败”
        }

        try
        {
            // 成功获取到锁后执行 Redis 发布操作
            var response = await RedisHelper.PublishAsync(param.Key, JsonConvert.SerializeObject(param.Data));
            return ApiResponse<long>.Success(response);
        }
        finally
        {
            // 确保在操作完成后释放锁
            await RedisHelper.DelAsync(lockKey);
        }
    }
    
    
}